function preprocessOCP ()
% Get bounds and set guess of NLP
%
global prob nlp;
global uGez
%% NLP Options


%% Necessary parameters
if ~isfield(prob, 'iRefine')
    prob.iRefine = 1;                         % The times the NLP has been executed.
else
    prob.iRefine = prob.iRefine + 1;          % New mesh refine
end
nlp.nnode = sum(prob.nodes{prob.iRefine});    % num of nodes in all segments 
nnode = nlp.nnode;                            % sum of "nele" in all segments

%% Get bounds on all nodes
% Get bounds of state x and control u.
row = 1; x_bnds = repmat([-inf inf], prob.nstate * (nnode + 1), 1);
for i = 1 : prob.nstate
    x_bnds(row, :) = prob.bnds.state_0(i,:);  % initial bnds
    %x_bnds(row, 2) = x_bnds(row, 2);
    row = row + nnode + 1;
end
row = 1; u_bnds = repmat([-inf inf], prob.nctrl * nnode, 1);
for i = 1 : prob.nctrl
   % u_bnds(row, :) = prob.bnds.ctrl_0(i,:);   % initial bnds
    row = row + nnode;
end
% Bounds of DAE
ode_bnds = zeros(prob.nstate * nnode, 2);
path_bnds = reshape(repmat(prob.bnds.paths(:)', nnode, 1), ...
    prob.npath * nnode, 2);
% TODO: event_bnds(:) 

nlp.var_bnds = [x_bnds; u_bnds; prob.bnds.params];
nlp.con_bnds = [ode_bnds; path_bnds];

%% indices
nlp.nvar = length(nlp.var_bnds);                       % variables
nlp.ncon = length(nlp.con_bnds);                       % constrains

tmp = [prob.nG *(nnode+1); prob.nG *(nnode+1); ...     % delta, omega
    2*prob.nB *nnode; nnode; prob.ncutG; prob.ncutL];  % V, coi, uG, uL
tmp = cumsum(tmp);                                     % Add
nlp.dltidx = reshape(1 : tmp(1), nnode+1, prob.nG)';
nlp.omgidx = reshape(tmp(1)+1 : tmp(2), nnode+1, prob.nG)';
nlp.Vidx = reshape(tmp(2)+1 : tmp(3), nnode, 2*prob.nB)'; 
nlp.coiidx = tmp(3)+1 : tmp(4);
nlp.uGidx = tmp(4)+1 : tmp(5); nlp.uLidx = tmp(5)+1 : tmp(6);

nlp.conidx = reshape(1 : nlp.ncon, nnode, prob.ndae)'; % Constrains Index

%% Get Collocation Points
nlp.collocI = collocateInfo(prob.segs{prob.iRefine}, prob.nodes{prob.iRefine}); 
t0 = prob.time(1); tf = prob.time(2);
t = [nlp.collocI.points; 1] * (tf - t0)/2 + (tf + t0)/2;
nlp.diffMat = ( 2/(tf - t0) ) * nlp.collocI.diffMat; 
nlp.collocT = t;

global guessSimFunc
%% Get guess for all nodes
if isfield(prob, 'p_ini')
    x_ini = zeros( nnode + 1, prob.nstate); u_ini = zeros(nnode, prob.nctrl);
    x_ini(1,:) = prob.bnds.state_0(:,1)'; u_ini(1,:) = prob.bnds.ctrl_0(:,1)';
    for i = 2 : nnode+1
        x_ini(i,:) = 0.99 * prob.bnds.state_0(:,1)';     
        if i ~= nnode+1, u_ini(i,:) = prob.bnds.ctrl_0(:,1)'; end
    end
    p_ini = prob.p_ini * ones(prob.nparam, 1);                    % uL and uG guess
    p_ini(uGez) = 0;
    nlp.guess = [x_ini(:); u_ini(:); p_ini(:)];
else
    [dltG, omgG, VG, coiG] = ...
        feval(guessSimFunc, t, prob.uG0, prob.uL0);
    p_ini = [prob.uG0; prob.uL0];
    p_ini(uGez) = 0;
    nlp.guess = [dltG(:); omgG(:); VG(:); coiG(:); p_ini];
end



end